<?php
class AspectProxy
{
	/***
	 * AOP实现方法
	 */
	function __call($method, $argument){
		$aspectMethod = '__aspect__'.$method;
		if(method_exists($this, $aspectMethod))
		{
			echo('aop before call<br />');

			//$ret = $this->$aspectMethod($argument);
			$ret = call_user_func_array(array($this, $aspectMethod), $argument);

			echo('aop after call<br />');

			return $ret;
		}else if(method_exists($this, $method)){
			return call_user_func_array(array($this, $method), $argument);
		}else{
			die('Class '.get_class($this).'没有找到为'.$method.'的方法');
		}
	}

	/**
	 * AOP类自动加载器
	 *
	 * @return boolean 类是否自动加载成功
	 */
	public static function autoload($className)
	{
		//侵入后的对象的类文件路径
		$aopfile = "aop_runtime/".$className.".php";

		//已经侵入过对象
		if(file_exists($aopfile)){
			include($aopfile);
		}else{
			//侵入对象操作
			$classFile = "services/".$className.".php";
			$source = file_get_contents($classFile);

			//侵入方法搜索正则
			$pattern = '/\/\/\[AspectMethod\]\s+(\w*)\s+function\s+(\w+)\s*\(/';
			preg_match_all($pattern, $source, $matches, PREG_SET_ORDER);
			foreach ($matches as $match){
				//只对public的方法做aop侵入处理
				if($match[1] == 'public' || $match[1]=='')
				{
					$source = str_replace($match[0], 'public function __aspect__'.$match[2].'(', $source);
				}else{
					$source = str_replace($match[0], str_replace('//[AspectMethod]', '', $match[0]), $source);
				}
			}

			//写入侵入后的文件内容
			file_put_contents($aopfile, $source, LOCK_EX);
			include($aopfile);
		}
		return class_exists($className, false) || interface_exists($className, false);
	}
}

//注册自动加载器
spl_autoload_register(array('AspectProxy','autoload'));
?>